package model

import (
	"fmt"
	"gorm.io/gorm"
	"shop/database/mysql"
)

// 商品sku表
type GoodsSku struct {
	gorm.Model
	ProValueId1 int64  `gorm:"column:pro_value_id1;type:int(11)"     json:"pro_value_id1"`
	ProValueId2 int64  `gorm:"column:pro_value_id2;type:int(11)"     json:"pro_value_id2"`
	ProValueId3 int64  `gorm:"column:pro_value_id3;type:int(11)"     json:"pro_value_id3"`
	Price       string `gorm:"column:price;type:varchar(20)"         json:"price"`
	VipPrice    string `gorm:"column:vip_price;type:varchar(20)"     json:"vip_price"`
	Stock       int64  `gorm:"column:stock;type:int(11)"             json:"stock"`
	GoodsId     int64  `gorm:"column:goods_id;type:int(11)"          json:"goods_id"`
}

// sku表详情显示
func (g *GoodsSku) GetGoodsSkuByPropertyValueIds(proValueId1, proValueId2, proValueId3 int) (info *GoodsSku, err error) {
	return info, mysql.WithMysql(func(db *gorm.DB) error {
		// 查找符合条件的记录，判断是否存在
		var count int64
		db.Table("goods_skus").
			Where("pro_value_id1 = ?", proValueId1).
			Where("pro_value_id2 = ?", proValueId2).
			Where("pro_value_id3 = ?", proValueId3).
			Count(&count)

		if count == 0 {
			// 如果没有找到记录，返回 nil 或者自定义的错误
			return nil
		}
		// 如果找到记录，正常执行查询并返回
		return db.Table("goods_skus").
			Where("pro_value_id1 = ?", proValueId1).
			Where("pro_value_id2 = ?", proValueId2).
			Where("pro_value_id3 = ?", proValueId3).
			First(&info).Error
	})
}

// 通过商品id获取sku信息
func (g *GoodsSku) SearchSkuByGoodsId(goodsId int) (info *GoodsSku, err error) {
	return info, mysql.WithMysql(func(db *gorm.DB) error {
		return db.Model(g).Where("goods_id = ?", goodsId).First(&info).Error
	})
}

// 获取sku表的skuID列表数据
func (g *GoodsSku) SearchSkuIDs(skuIDs []uint) (info []*GoodsSku, err error) {
	return info, mysql.WithMysql(func(db *gorm.DB) error {
		return db.Model(g).Where("id int (?)", skuIDs).Find(&info).Error
	})
}

// 通过获取的skuID数据扣减下单时的商品库存
type UpdateStock struct {
	SkuID uint `json:"sku_id"`
	Num   uint `json:"num"`
}

func (g *GoodsSku) UpdateStock(in []*UpdateStock) (err error) {
	var skuIDs []uint
	for _, sku := range in {
		skuIDs = append(skuIDs, sku.SkuID)
	}

	var skuInfos []*GoodsSku

	return mysql.WithMysql(func(db *gorm.DB) error {
		return db.Transaction(func(tx *gorm.DB) error {
			//在事务中查询商品 SKU 信息，并对查询到的记录加锁（FOR UPDATE），以确保在事务提交之前，其他事务无法修改这些记录
			err = tx.Set("gorm:query_option", "FOR UPDATE").Where("id in (?)", skuIDs).Find(&skuInfos).Error
			if err != nil {
				return err
			}

			skuMap := make(map[uint]*GoodsSku)
			for _, val := range skuMap {
				skuMap[val.ID] = val
			}

			for _, val := range in {
				skuInfo := skuMap[val.SkuID]
				if skuInfo.Stock < int64(val.Num) {
					return fmt.Errorf("库存不足")
				}
				err = tx.Model(g).Where("sku_id = ?", val.SkuID).Update("stock", gorm.Expr("stock-", val.Num)).Error
				if err != nil {
					return err
				}
			}
			return nil
		})
	})
}
